﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using Eflong.DataAccess;
using Eflong.DTO.Wcf;
using Eflong.MonitoringLib.MonitoringUnit;
using Eflong.Utility;
using CoalMineInfo = Eflong.DTO.Wcf.CoalMineInfo;

namespace Eflong.Monitor
{
    public class CoalMineInfoTask
    {
        /// <summary>
        /// 当前的联网矿实时状态集合
        /// </summary>
        public Dictionary<long , CoalMineInfo> dic_CoalMineInfo = new Dictionary<long , CoalMineInfo>( );

        private RealDataTask realDataTask;

        /// <summary>
        /// 系统是否有数据库等故障
        /// </summary>
        public bool IsFault { get; set; }

        public List<CoalMineInfo> list_CoalMineBreakInfo = new List<CoalMineInfo>( );

        public int CoalMineCount { get; set; }

        public EflogMonitorServer server { get; set; }

        private CoalMineInfoTask( )
        {
        }

        private static CoalMineInfoTask _instance = null;

        public static CoalMineInfoTask Instance( )
        {
            if ( _instance == null )
            {
                _instance = new CoalMineInfoTask( );
            }
            return _instance;
        }

        /// <summary>
        /// 清除当前的联网煤矿的中断记录
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        public int ClearConnStatusData( )
        {
            int result = 0;
            string cmdText;

            // 清除当前组合报警

            try
            {
                using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
                {
                    LogWrapper.Logger.Debug( "RealMonitorTask DELETE FROM  [KW_ConnStatusData] ..." );

                    cmdText = "DELETE FROM  [KW_ConnStatusData] where 1=1 ";
                    result = db.ExecuteCommand( cmdText , new object[ ] { } );
                }
            }
            catch ( SqlException ex )
            {
                LogWrapper.Logger.Error( "删除当前联网中断记录 " + ex.Message );
            }
            return result;
        }

        public long GetCoalMineMaxId( )
        {
            return dic_CoalMineInfo.Keys.Max( );
        }

        /// <summary>
        /// 根据矿号得到联网矿信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public CoalMineInfo GetCoalMineInfoById( long id )
        {
            if ( dic_CoalMineInfo.ContainsKey( id ) )
            {
                return dic_CoalMineInfo[ id ];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 加载最新的各矿联网的状态信息
        /// </summary>
        public bool CoalMineInfoInit( )
        {
            bool result = false;
            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
            {
                try
                {
                    var coalMineItems = from item in db.CoalMineInfo select item;
                    foreach ( var item in coalMineItems )
                    {
                        if ( !dic_CoalMineInfo.ContainsKey( item.Id ) )
                        {
                            dic_CoalMineInfo.Add( item.Id , new CoalMineInfo( ) );
                        }
                        CoalMineInfo info = dic_CoalMineInfo[ item.Id ];

                        info.Id = item.Id;
                        info.IPAddr = item.IPAddr;
                        info.Name = item.Name;

                        BaseCoalMineUnit coalMineUint = CoalMineUnitManager.Instance( ).GetCoalMineUnit( item.Id );

                        if ( coalMineUint != null && !coalMineUint.m_bConnected )
                        {
                            item.ConnectionStatus = ( byte )ConnectStates.FaultState;
                        }
                        else
                        {
                            item.ConnectionStatus = ( byte )ConnectStates.UnKnownState;
                        }

                        if ( coalMineUint != null )
                        {
                            info.BeginTime = coalMineUint.m_Time;
                        }
                        else
                        {
                            info.BeginTime = DateTime.Now;
                        }

                        // 从联网状态的当前表中获取异常信息
                        bool bFind = false;

                        var coalMineRecords = ( from record in db.KW_ConnStatusData
                                                where record.CoalMineId == item.Id
                                                orderby record.AutoId descending
                                                select record );
                        if ( coalMineRecords.Count( ) > 0 )
                        {
                            var coalMineRecord = coalMineRecords.Take( 1 ).Single( );

                            //info.Time = coalMineRecord.Time;
                            info.BeginTime = Convert.ToDateTime( coalMineRecord.BeginTime );
                            info.Time = info.BeginTime;
                            info.ConnectionStatus = ( ConnectStates )( coalMineRecord.State );
                            info.Causation = coalMineRecord.Causation;
                            info.Measure = coalMineRecord.Measure;

                            info.MeasureTime = Convert.ToDateTime( coalMineRecord.MeasureTime );
                            info.ChangedTime = info.BeginTime;

                            Console.WriteLine( info.Name );
                            Console.WriteLine( info.Time.ToShortDateString( ) );
                            Console.WriteLine( info.ConnectionStatus );
                            bFind = true;
                        }

                        // 如果当前联网状态正常，并且在当前联网状态异常表中无记录，则也设置成正常
                        if ( ( item.ConnectionStatus == ( byte )ConnectStates.NormalState || item.ConnectionStatus == ( byte )ConnectStates.AlertState ) )
                        {
                            info.SetNormal( );
                        }
                    }
                    result = true;
                }
                catch ( Exception ex )
                {
                    LogWrapper.Logger.Error( "CoalMineInfoInit " + ex.Message );
                    result = false;
                }
            }

            return result;
        }

        /// <summary>
        ///  加载联网矿信息
        /// </summary>
        public void LoadCoalMineInfoFromDB( )
        {
            try
            {
                using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
                {
                    CoalMineInfo info;
                    var coalMineItems = from item in db.CoalMineInfo orderby item.Id select item;
                    foreach ( var item in coalMineItems )
                    {
                        if ( !dic_CoalMineInfo.ContainsKey( item.Id ) && item.IPAddr != "0.0.0.0" )
                        {
                            dic_CoalMineInfo.Add( item.Id , new CoalMineInfo( ) );
                            dic_CoalMineInfo[ item.Id ].SetFault( );
                        }
                        if ( dic_CoalMineInfo.ContainsKey( item.Id ) )
                        {
                            info = dic_CoalMineInfo[ item.Id ];
                        }
                        else
                        {
                            continue;
                        }

                        info.Id = item.Id;
                        if ( item.IPAddr == "0.0.0.0" && info.IPAddr != "0.0.0.0" )
                        {
                            // 联网矿不使用了

                            info.SetFault( );
                        }
                        if ( info.IPAddr != item.IPAddr || info.Name != item.Name )
                        {
                            // 联网的信息改变，需要记录

                            info.IPAddr = item.IPAddr;
                            info.Name = item.Name;
                            Set_CoalMineUnit( info );

                            info.SetToNeedRecord( );
                        }

                        // 是否长时间不改变的判断

                        if ( info.IsDataNoChanged( ) )
                        {
                            // info.SetDataNoChanged();
                        }
                        if ( !info.IsRecord )
                        {
                            // 联网矿未做记录，需要记录

                            info.SetToNeedRecord( );
                        }
                    }
                }
            }
            catch ( SqlException ex )
            {
                LogWrapper.Logger.Error( "加载联网矿状态信息记录: " + ex.Message );
            }
        }

        /// <summary>
        /// 设置到联网矿的信息改变
        /// </summary>
        /// <param name="info"></param>
        private static void Set_CoalMineUnit( CoalMineInfo info )
        {
            BaseCoalMineUnit coalMineUnit = CoalMineUnitManager.Instance( ).GetCoalMineUnit( info.Id );
            if ( coalMineUnit != null )
            {
                coalMineUnit.m_strIPAddr = info.IPAddr;
                coalMineUnit.m_Time = info.Time;
            }
        }

        /// <summary>
        /// 把当前联网状态异常的矿情况写入当前联网状态表中,
        /// 并把回复正常状态的矿情况写入历史状态表中
        /// </summary>
        public void SaveConnStatusDataToDB( )
        {
            bool bChanged = false;
            List<int> list = new List<int>( );
            try
            {
                var query = from coalMineInfo in dic_CoalMineInfo.Values where coalMineInfo.IsNeedRecord select coalMineInfo;
                foreach ( CoalMineInfo info in query )
                {
                    bChanged = true;
                    if ( info.IsNormal( ) || info.IPAddr == "0.0.0.0" )
                    {
                        // 已经恢复正常了 或者 IP地址为空
                        // 从当前联网状态异常表中，找到相应联网矿的记录，取出相应的内容；
                        // 并把相应的记录删除
                        if ( info.IPAddr == "0.0.0.0" )
                        {
                            // 删除IP地址为不用的煤矿信息
                            //dic_CoalMineInfo.Remove(info.Id);
                            list.Add( info.Id );
                            LogWrapper.Logger.Info( "删除IP地址为0.0.0.0 煤矿： " + info.Name );
                        }
                        bool bFind = false;
                        using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
                        {
                            var records = ( from record in db.KW_ConnStatusData
                                            where record.CoalMineId == info.Id
                                            select record );
                            foreach ( KW_ConnStatusData connStatusData in records )
                            {
                                // 从当前表中，发现记录，取出相应的中断原因、采取的措施及时刻
                                // 获取当前网络状态恢复的矿记录,写入联网状态历史表中
                                // 并把当前联网状态异常表中，删除相应的记录
                                try
                                {
                                    KW_HisConnStatusData data = new KW_HisConnStatusData( );
                                    data.CoalMineId = info.Id;
                                    data.CoalMineName = info.Name;
                                    data.IPAddr = info.IPAddr;
                                    if ( info.BeginTime.Year >= 2010 )
                                    {
                                        data.BeginTime = info.BeginTime;
                                    }
                                    if ( info.EndTime.Year >= 2010 )
                                    {
                                        data.EndTime = info.EndTime;
                                    }
                                    data.Measure = connStatusData.Measure;
                                    DateTime tm = Convert.ToDateTime( connStatusData.MeasureTime );
                                    if ( tm.Year >= 2009 )
                                    {
                                        data.MeasureTime = tm;
                                    }
                                    if ( info.EndTime.Year < 2009 )
                                    {
                                        data.EndTime = DateTime.Now;
                                    }
                                    data.Causation = connStatusData.Causation;
                                    data.State = connStatusData.State;
                                    if ( !bFind )
                                    {
                                        DatabaseHelper.Insert<KW_HisConnStatusData>( data );
                                        dic_CoalMineInfo[ info.Id ].SetHasRecord( );
                                    }
                                    DatabaseHelper.Delete<KW_ConnStatusData>( connStatusData );
                                    bFind = true;
                                }
                                catch ( Exception ex )
                                {
                                    LogWrapper.Logger.Error( this , ex );
                                }
                            }
                        }
                        if ( !bFind )
                        {
                            // 当前表中没有异常记录，则直接写入历史表中
                            try
                            {
                                KW_HisConnStatusData data = new KW_HisConnStatusData( );
                                data.CoalMineId = info.Id;
                                data.CoalMineName = info.Name;

                                data.BeginTime = info.BeginTime;

                                data.EndTime = DateTime.Now;

                                data.State = Convert.ToByte( info.ConnectionStatus );
                                data.IPAddr = info.IPAddr;
                                DatabaseHelper.Insert<KW_HisConnStatusData>( data );
                            }
                            catch ( Exception ex )
                            {
                                LogWrapper.Logger.Error( this , ex );
                            }
                            dic_CoalMineInfo[ info.Id ].SetHasRecord( );
                        }
                    }
                    else if ( info.IsFault( ) )
                    {
                        // 发生异常了

                        bool bFind = false;
                        using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
                        {
                            var records = ( from record in db.KW_ConnStatusData
                                            where record.CoalMineId == info.Id
                                            select record );
                            if ( records.Count( ) > 0 )
                            {
                                // 在当前的中断表中，已经有记录了
                                dic_CoalMineInfo[ info.Id ].SetHasRecord( );
                                bFind = true;
                            }
                        }
                        if ( !bFind )
                        {
                            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
                            {
                                // 写入联网状态异常当前表中

                                try
                                {
                                    KW_ConnStatusData data = new KW_ConnStatusData( );
                                    data.CoalMineId = info.Id;
                                    data.CoalMineName = info.Name;
                                    if ( info.BeginTime.Year >= 2010 )
                                    {
                                        data.BeginTime = info.BeginTime;
                                    }
                                    else
                                    {
                                        data.BeginTime = DateTime.Now;
                                    }
                                    data.EndTime = DateTime.Now;

                                    data.IPAddr = info.IPAddr;
                                    data.State = Convert.ToByte( info.ConnectionStatus );
                                    DatabaseHelper.Insert<KW_ConnStatusData>( data );
                                    dic_CoalMineInfo[ info.Id ].SetHasRecord( );
                                }
                                catch ( Exception ex )
                                {
                                    LogWrapper.Logger.Error( this , ex );
                                }
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                LogWrapper.Logger.Error( "SaveConnStatusDataToDB -> " + ex.Message );
            }
            finally
            {
                if ( bChanged )
                {
                    DeleteEmptyIPAddr( list );
                    GenCoalMineInfos( );
                }
            }
        }

        /// <summary>
        /// 程序退出时，设置联网状态为未知
        /// </summary>
        public void SaveQuitState( )
        {
            foreach ( long nId in dic_CoalMineInfo.Keys )
            {
                CoalMineInfo info = dic_CoalMineInfo[ nId ];
                info.ConnectionStatus = ConnectStates.UnKnownState;
                info.IsNeedRecord = true;
                info.IsRecord = false;
                info.Causation = "程序退出";
                info.ChangedTime = DateTime.Now;
                UpdateCoalMineInfo( ( uint )nId , ConnectStates.UnKnownState );
            }

            SaveCoalMineRecordToDB( );
            SaveConnStatusDataToDB( );
        }

        /// <summary>
        /// 保存当前变化的联网矿记录到数据表
        /// </summary>
        public void SaveCoalMineRecordToDB( )
        {
            try
            {
                var infos = from info in dic_CoalMineInfo.Values
                            where ( info.IsNeedRecord && !info.IsRecord )
                            select info;
                if ( infos.Count( ) > 0 )
                {
                    try
                    {
                        foreach ( CoalMineInfo info in infos )
                        {
                            CoalMineInfoRecord record = new CoalMineInfoRecord( );

                            record.Id = info.Id;
                            record.IPAddr = info.IPAddr;
                            record.Name = info.Name;
                            if ( info.Time.Year >= 2005 )
                            {
                                record.Time = info.Time;
                            }

                            record.ConnectionStatus = Convert.ToByte( info.ConnectionStatus );
                            record.Causation = info.Causation;
                            record.Measure = info.Measure;

                            if ( info.MeasureTime.Year >= 2005 )
                            {
                                record.MeasureTime = info.MeasureTime;
                            }
                            DatabaseHelper.Insert<CoalMineInfoRecord>( record );

                            //info.IsNeedRecord = false;
                            //info.IsRecord = true;
                        }
                    }
                    catch ( SqlException ex )
                    {
                        LogWrapper.Logger.Error( "保存联网状态信息记录" + ex.Message );

                        // //MyShowMessage.MySqlExceptionShow(ex, "保存联网状态信息记录");
                    }
                }
            }
            catch ( Exception ex )
            {
                //MyShowMessage.MyExceptionShow(ex, "保存联网状态信息记录");
                LogWrapper.Logger.Error( "保存联网状态信息记录 -> " + ex.Message );
                IsFault = true;
            }
        }

        /// <summary>
        /// 删除Ip地址为 "0.0.0.0" 的矿信息
        /// </summary>
        /// <param name="list"></param>
        public void DeleteEmptyIPAddr( List<int> list )
        {
            if ( list.Count > 0 )
            {
                for ( int n = 0; n < list.Count; n++ )
                {
                    int id = list[ n ];
                    dic_CoalMineInfo.Remove( id );
                }
                list.Clear( );
            }
            list = null;
        }

        /// <summary>
        /// 产生联网矿的相关信息，并向Server 发布改变信息
        /// </summary>
        public void GenCoalMineInfos( )
        {
            CoalMineCount = dic_CoalMineInfo.Count;
            List<CoalMineInfo> list = new List<CoalMineInfo>( );
            foreach ( var item in dic_CoalMineInfo.Where( info => info.Value.ConnectionStatus <= ( ConnectStates.UnKnownState ) || info.Value.ConnectionStatus >= ( ConnectStates.FaultState ) ) )
            {
                list.Add( item.Value );
            }
            list_CoalMineBreakInfo = list.ToList( );

            list.Clear( );
            list = null;

            server.CoalMineCount = CoalMineCount;
            server.CoalMineBreakCount = list_CoalMineBreakInfo.Count;
            server.list_CoalMineBreakInfo = list_CoalMineBreakInfo;
            server.CoalMineCountChanged( );
            server.CoalMineInfoChanged( );
        }

        /// <summary>
        /// 设置测点正常
        /// </summary>
        /// <param name="Id"></param>
        public void SetDataNormalDemo( int Id )
        {
            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
            {
                var q = from item in db.AnalogCurrentData where item.CoalMineId == Id select item;

                foreach ( var item in q )
                {
                    float f = 1.2f;
                    byte state = 18;
                    DateTime time = DateTime.Now;

                    DatabaseHelper.Update<AnalogCurrentData>( item , r => { r.MonUnitData = f; r.MonUnitState = state; r.StateChangeTime = time; r.DataChangeTime = time; } );
                    break;
                }

                var qd = from item in db.DigitalCurrentData where item.CoalMineId == Id select item;

                foreach ( var item in qd )
                {
                    byte v = 1;
                    byte state = 18;
                    DateTime time = DateTime.Now;

                    DatabaseHelper.Update<DigitalCurrentData>( item , r => { r.MonUnitData = v; r.MonUnitState = state; r.StateChangeTime = time; } );
                    break;
                }
            }
        }

        /// <summary>
        /// 设置测点数据不变化
        /// </summary>
        /// <param name="Id"></param>
        public void SetDataNoChangedDemo( int Id )
        {
            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
            {
                var q = from item in db.AnalogCurrentData where item.CoalMineId == Id select item;

                foreach ( var item in q )
                {
                    float f = 1.2f;
                    byte state = 18;
                    DateTime time = DateTime.Today;

                    DatabaseHelper.Update<AnalogCurrentData>( item , r => { r.MonUnitData = f; r.MonUnitState = state; r.StateChangeTime = time; r.DataChangeTime = time; } );
                }

                var qd = from item in db.DigitalCurrentData where item.CoalMineId == Id select item;

                foreach ( var item in qd )
                {
                    byte v = 1;
                    byte state = 18;
                    DateTime time = DateTime.Today;

                    DatabaseHelper.Update<DigitalCurrentData>( item , r => { r.MonUnitData = v; r.MonUnitState = state; r.StateChangeTime = time; } );
                }
            }
        }

        /// <summary>
        /// 设置 IP地址为 "0.0.0.0"
        /// </summary>
        /// <param name="Id"></param>
        public void SetZeroIPDemo( int Id , out string sIPAddr )
        {
            string s = "0.0.0.0";
            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
            {
                var q = from item in db.CoalMineInfo where item.Id == Id select item;
                foreach ( var item in q )
                {
                    s = item.IPAddr;
                    DatabaseHelper.Update<Eflong.DataAccess.CoalMineInfo>( item , r => { r.IPAddr = "0.0.0.0"; } );
                    break;
                }
            }
            sIPAddr = s;
        }

        public void SetIPAddrDemo( int Id , string sIPAddr )
        {
            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
            {
                var q = from item in db.CoalMineInfo where item.Id == Id select item;
                foreach ( var item in q )
                {
                    DatabaseHelper.Update<Eflong.DataAccess.CoalMineInfo>( item , r => { r.IPAddr = sIPAddr; } );
                    break;
                }
            }
        }

        /// <summary>
        /// 更新联网矿状态信息
        /// </summary>
        /// <param name="nId">矿Id</param>
        /// <param name="state">联网状态</param>
        public void UpdateCoalMineInfo( uint nId , ConnectStates state )
        {
            CoalMineInfo cmi;

            BaseCoalMineUnit bcu = CoalMineUnitManager.Instance( ).GetCoalMineUnit( ( long )nId );
            if ( bcu == null )
            {
                return;
            }
            if ( dic_CoalMineInfo.Count == 0 || !dic_CoalMineInfo.ContainsKey( nId ) )
            {
                lock ( dic_CoalMineInfo )
                {
                    cmi = new CoalMineInfo( );
                    cmi.Id = ( int )nId;
                    if ( bcu == null )
                    {
                        throw new NullReferenceException( "联网矿信息不存在" );
                    }
                    cmi.Name = bcu.m_strName;
                    cmi.IPAddr = bcu.m_strIPAddr;
                    cmi.ChangedTime = bcu.m_Time;
                    cmi.BeginTime = bcu.m_Time;
                    dic_CoalMineInfo.Add( nId , cmi );
                }
            }
            else
            {
                cmi = dic_CoalMineInfo[ nId ];
            }
            cmi.ConnectionStatus = state;
            cmi.BeginTime = bcu.m_Time;

            UpdateCoalMineInfoToDB( cmi );
        }

        /// <summary>
        /// 更新联网矿信息到数据表
        /// </summary>
        /// <param name="cmi"></param>
        private void UpdateCoalMineInfoToDB( CoalMineInfo cmi )
        {
            try
            {
                //需要考虑给联网矿的状态加入时刻
                using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
                {
                    bool bFind = false;
                    var q = from item in db.CoalMineInfo where item.Id == cmi.Id select item;
                    foreach ( var item in q )
                    {
                        bFind = true;
                        try
                        {
                            DatabaseHelper.Update<Eflong.DataAccess.CoalMineInfo>( item , r => { r.ConnectionStatus = Convert.ToByte( cmi.ConnectionStatus ); } ); // r.IPAddr = cmi.IPAddr; r.Name = cmi.Name;
                        }
                        catch ( Exception ex )
                        {
                            LogWrapper.Logger.Error( "UpdateCoalMineInfoToDB" );
                            LogWrapper.Logger.Error( ex );
                        }
                        break;
                    }
                    if ( !bFind )
                    {
                        try
                        {
                            Eflong.DataAccess.CoalMineInfo r = new DataAccess.CoalMineInfo( ) { Id = cmi.Id , Name = cmi.Name , IPAddr = cmi.IPAddr , ConnectionStatus = Convert.ToByte( cmi.ConnectionStatus ) };

                            DatabaseHelper.Insert<Eflong.DataAccess.CoalMineInfo>( r );
                        }
                        catch ( Exception ex )
                        {
                            LogWrapper.Logger.Error( "UpdateCoalMineInfoToDB" );
                            LogWrapper.Logger.Error( ex );
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                LogWrapper.Logger.Error( "更新联网矿信息到数据表" );
                LogWrapper.Logger.Error( ex );
            }
        }

        /// <summary>
        /// 更新传感器实时数据信息
        /// </summary>
        /// <param name="nId"></param>
        public void UpdateSensorsDemo( uint nId )
        {
            if ( realDataTask == null ) realDataTask = RealDataTask.Instance( );

            using ( var db = DatabaseHelper.GetKWSystemDBDataContext( ) )
            {
                var q = from item in db.AnalogCurrentData where item.CoalMineId == nId select item;

                foreach ( var item in q )
                {
                    float f = 1.2f;
                    byte state = 18;
                    DateTime time = DateTime.Today;

                    DatabaseHelper.Update<AnalogCurrentData>( item , r => { r.MonUnitData = f; r.MonUnitState = state; r.StateChangeTime = time; r.DataChangeTime = time; } );
                }

                var qd = from item in db.DigitalCurrentData where item.CoalMineId == nId select item;

                foreach ( var item in qd )
                {
                    byte v = 1;
                    byte state = 18;
                    DateTime time = DateTime.Today;

                    DatabaseHelper.Update<DigitalCurrentData>( item , r => { r.MonUnitData = v; r.MonUnitState = state; r.StateChangeTime = time; } );
                }
            }
        }
    }
}